<template>
  <div class="vue3-demo">
    <h2 class="section-title">Vue 3 特性演示</h2>
    
    <div class="demo-grid">
      <!-- Composition API -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>Composition API</h3>
          <button class="code-toggle" @click="toggleCode('composition')">
            {{ showCode.composition ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.composition">
            <pre class="code-viewer"><code>// Composition API 示例
import { ref, computed, watch, onMounted } from 'vue'

// 响应式状态
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
const lastAction = ref('')

// 监听器
watch(count, (newValue, oldValue) => {
  console.log(`计数从 ${oldValue} 变为 ${newValue}`)
})

// 生命周期钩子
onMounted(() => {
  console.log('组件已挂载')
})

// 可复用的组合式函数
function useCounter() {
  const count = ref(0)
  const increment = () => count.value++
  const decrement = () => count.value--
  return { count, increment, decrement }
}

const increment = () => {
  count.value++
  lastAction.value = '增加'
}

const decrement = () => {
  count.value--
  lastAction.value = '减少'
}

const reset = () => {
  count.value = 0
  lastAction.value = '重置'
}
</code></pre>
          </div>
          <div class="demo-preview">
            <div class="feature-list">
              <div class="feature-item">
                <span class="feature-label">计数器:</span>
                <span class="feature-value">{{ compositionDemo.count }}</span>
              </div>
              <div class="feature-item">
                <span class="feature-label">双倍值:</span>
                <span class="feature-value">{{ compositionDemo.doubleCount }}</span>
              </div>
            </div>
            <div class="interactive-demo">
              <div class="input-group">
                <button @click="compositionDemo.increment">增加</button>
                <button @click="compositionDemo.decrement">减少</button>
                <button @click="compositionDemo.reset">重置</button>
              </div>
              <div class="result-display" v-if="compositionDemo.lastAction">
                上次操作: {{ compositionDemo.lastAction }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Script Setup -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>Script Setup</h3>
          <button class="code-toggle" @click="toggleCode('setup')">
            {{ showCode.setup ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.setup">
            <pre class="code-viewer"><code>// Script Setup 语法糖
&lt;script setup&gt;
import { ref, computed } from 'vue'

// 响应式状态
const count = ref(0)

// 计算属性
const double = computed(() => count.value * 2)

// 方法
const increment = () => count.value++

// Props 类型声明
defineProps&lt;{
  title: string
  count?: number
}&gt;()

// Emits 类型声明
defineEmits&lt;{
  (e: 'update', value: number): void
  (e: 'delete'): void
}&gt;()

// 暴露给父组件的属性
defineExpose({
  count,
  increment
})
&lt;/script&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="setup-demo">
              <div class="counter-card">
                <div class="counter-display">
                  <span class="counter-number">{{ setupDemo.count }}</span>
                </div>
                <div class="counter-controls">
                  <button @click="setupDemo.decrement">-</button>
                  <button @click="setupDemo.increment">+</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Teleport -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>Teleport</h3>
          <button class="code-toggle" @click="toggleCode('teleport')">
            {{ showCode.teleport ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.teleport">
            <pre class="code-viewer"><code>// Teleport 示例
&lt;template&gt;
  &lt;button @click="showModal = true"&gt;
    打开模态框
  &lt;/button&gt;

  &lt;Teleport to="body"&gt;
    &lt;div v-if="showModal" class="modal"&gt;
      &lt;h3&gt;模态框内容&lt;/h3&gt;
      &lt;button @click="showModal = false"&gt;
        关闭
      &lt;/button&gt;
    &lt;/div&gt;
  &lt;/Teleport&gt;
&lt;/template&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <button @click="teleportDemo.showModal = true">打开模态框</button>
            <Teleport to="body">
              <div v-if="teleportDemo.showModal" class="modal-overlay">
                <div class="modal">
                  <h3>Teleport 模态框</h3>
                  <p>这个模态框被传送到了 body 元素中</p>
                  <button @click="teleportDemo.showModal = false">关闭</button>
                </div>
              </div>
            </Teleport>
          </div>
        </div>
      </div>

      <!-- Suspense -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>Suspense</h3>
          <button class="code-toggle" @click="toggleCode('suspense')">
            {{ showCode.suspense ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.suspense">
            <pre class="code-viewer"><code>// AsyncComponent.vue
&lt;script setup&gt;
const data = await fetch('https://api.example.com/data')
const result = await data.json()
&lt;/script&gt;

// 父组件
&lt;template&gt;
  &lt;Suspense&gt;
    &lt;template #default&gt;
      &lt;AsyncComponent /&gt;
    &lt;/template&gt;
    &lt;template #fallback&gt;
      &lt;div&gt;加载中...&lt;/div&gt;
    &lt;/template&gt;
  &lt;/Suspense&gt;
&lt;/template&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="suspense-demo">
              <div class="demo-controls">
                <button 
                  @click="loadSuspenseData"
                  :disabled="suspenseDemo.loading"
                  class="primary-button"
                >
                  {{ suspenseDemo.loading ? '加载中...' : '加载数据' }}
                </button>
              </div>
              <div v-if="suspenseDemo.error" class="error-message">
                {{ suspenseDemo.error }}
              </div>
              <div v-if="suspenseDemo.data" class="data-card">
                <div class="data-header">
                  <span class="data-id">#{{ suspenseDemo.data.id }}</span>
                  <span class="data-timestamp">{{ suspenseDemo.data.timestamp }}</span>
                </div>
                <div class="data-content">
                  <h4>{{ suspenseDemo.data.title }}</h4>
                  <div class="data-info">
                    <span class="data-status" :class="suspenseDemo.data.status">
                      {{ suspenseDemo.data.status }}
                    </span>
                    <span class="data-type">{{ suspenseDemo.data.type }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 响应式系统 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>响应式系统</h3>
          <button class="code-toggle" @click="toggleCode('reactivity')">
            {{ showCode.reactivity ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.reactivity">
            <pre class="code-viewer"><code>// 响应式系统示例
import { ref, reactive, computed } from 'vue'

// ref 用于基础类型
const message = ref('Hello Vue 3')

// reactive 用于对象
const user = reactive({
  name: 'Vue',
  age: 3
})

// computed 计算属性
const userInfo = computed(() => 
  `${user.name} (${user.age}岁)`
)</code></pre>
          </div>
          <div class="demo-preview">
            <div class="feature-list">
              <div class="feature-item">
                <span class="feature-label">消息:</span>
                <span class="feature-value">{{ reactivityDemo.message }}</span>
              </div>
              <div class="feature-item">
                <span class="feature-label">用户信息:</span>
                <span class="feature-value">{{ reactivityDemo.userInfo }}</span>
              </div>
            </div>
            <div class="interactive-demo">
              <div class="input-group">
                <input v-model="reactivityDemo.message" placeholder="修改消息">
                <input v-model="reactivityDemo.user.name" placeholder="修改用户名">
                <input v-model.number="reactivityDemo.user.age" type="number" placeholder="修改年龄">
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 组合式API进阶 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>组合式API进阶</h3>
          <button class="code-toggle" @click="toggleCode('compositionAdvanced')">
            {{ showCode.compositionAdvanced ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.compositionAdvanced">
            <pre class="code-viewer"><code>// 组合式API进阶示例
import { ref, reactive, computed, watch, watchEffect, onMounted, onUnmounted } from 'vue'

// 自定义组合式函数
function useMousePosition() {
  const x = ref(0)
  const y = ref(0)
  
  function updatePosition(e) {
    x.value = e.clientX
    y.value = e.clientY
  }
  
  onMounted(() => {
    window.addEventListener('mousemove', updatePosition)
  })
  
  onUnmounted(() => {
    window.removeEventListener('mousemove', updatePosition)
  })
  
  return { x, y }
}

// 使用组合式函数
const { x, y } = useMousePosition()

// watchEffect 自动追踪依赖
watchEffect(() => {
  console.log(`鼠标位置: (${x.value}, ${y.value})`)
})

// 防抖函数
function useDebounce(fn, delay) {
  let timeoutId
  return (...args) => {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => fn(...args), delay)
  }
}</code></pre>
          </div>
          <div class="demo-preview">
            <div class="advanced-demo">
              <div class="mouse-tracker">
                <h4>鼠标位置追踪</h4>
                <div class="position-display">
                  <div class="position-item">
                    <span class="position-label">X:</span>
                    <span class="position-value">{{ mousePosition.x }}</span>
                  </div>
                  <div class="position-item">
                    <span class="position-label">Y:</span>
                    <span class="position-value">{{ mousePosition.y }}</span>
                  </div>
                </div>
                <div class="mouse-area" @mousemove="updateMousePosition">
                  在此区域移动鼠标
                </div>
              </div>
              <div class="debounce-demo">
                <h4>防抖输入</h4>
                <input 
                  v-model="debounceInput" 
                  placeholder="输入文本（带防抖）"
                  class="debounce-input"
                >
                <div class="debounce-result">
                  防抖结果: {{ debounceResult }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 响应式系统进阶 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>响应式系统进阶</h3>
          <button class="code-toggle" @click="toggleCode('reactivityAdvanced')">
            {{ showCode.reactivityAdvanced ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.reactivityAdvanced">
            <pre class="code-viewer"><code>// 响应式系统进阶示例
import { 
  ref, 
  reactive, 
  readonly, 
  shallowRef, 
  shallowReactive,
  toRefs,
  toRaw,
  markRaw,
  customRef
} from 'vue'

// 只读响应式对象
const original = reactive({ count: 0 })
const copy = readonly(original)

// 浅层响应式
const shallowState = shallowReactive({
  nested: { count: 0 }
})

// 获取原始数据
const raw = toRaw(shallowState)

// 自定义 ref
function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}

// 使用自定义 ref
const debouncedText = useDebouncedRef('')

// 标记为非响应式
const nonReactive = markRaw({ id: 1 })</code></pre>
          </div>
          <div class="demo-preview">
            <div class="advanced-reactivity-demo">
              <div class="reactivity-section">
                <h4>只读响应式</h4>
                <div class="reactivity-controls">
                  <button @click="reactivityAdvancedDemo.incrementOriginal">增加原始值</button>
                  <button @click="reactivityAdvancedDemo.tryModifyCopy">尝试修改只读值</button>
                </div>
                <div class="reactivity-display">
                  <div class="reactivity-item">
                    <span class="reactivity-label">原始值:</span>
                    <span class="reactivity-value">{{ reactivityAdvancedDemo.original.count }}</span>
                  </div>
                  <div class="reactivity-item">
                    <span class="reactivity-label">只读值:</span>
                    <span class="reactivity-value">{{ reactivityAdvancedDemo.copy.count }}</span>
                  </div>
                </div>
              </div>
              <div class="reactivity-section">
                <h4>浅层响应式</h4>
                <div class="reactivity-controls">
                  <button @click="reactivityAdvancedDemo.updateNested">更新嵌套属性</button>
                </div>
                <div class="reactivity-display">
                  <div class="reactivity-item">
                    <span class="reactivity-label">浅层值:</span>
                    <span class="reactivity-value">{{ reactivityAdvancedDemo.shallowState.value }}</span>
                  </div>
                  <div class="reactivity-item">
                    <span class="reactivity-label">嵌套值:</span>
                    <span class="reactivity-value">{{ reactivityAdvancedDemo.shallowState.nested.count }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 自定义指令 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>自定义指令</h3>
          <button class="code-toggle" @click="toggleCode('directive')">
            {{ showCode.directive ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.directive">
            <pre class="code-viewer"><code>// 自定义指令示例
// 自动聚焦指令
const vFocus = {
  mounted: (el) => el.focus()
}

// 高亮指令
const vHighlight = {
  mounted: (el, binding) => {
    el.style.backgroundColor = binding.value || '#ff0'
  },
  updated: (el, binding) => {
    el.style.backgroundColor = binding.value || '#ff0'
  }
}

// 点击外部指令
const vClickOutside = {
  mounted(el, binding) {
    el._clickOutside = (event) => {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event)
      }
    }
    document.addEventListener('click', el._clickOutside)
  },
  unmounted(el) {
    document.removeEventListener('click', el._clickOutside)
  }
}

// 使用指令
&lt;input v-focus&gt;
&lt;div v-highlight="'#ff0'"&gt;高亮文本&lt;/div&gt;
&lt;div v-click-outside="handleClickOutside"&gt;点击外部关闭&lt;/div&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="directive-demo">
              <div class="directive-section">
                <h4>自动聚焦</h4>
                <input 
                  v-focus 
                  placeholder="自动获取焦点"
                  class="directive-input"
                >
              </div>
              <div class="directive-section">
                <h4>高亮效果</h4>
                <div class="color-picker">
                  <button 
                    v-for="color in directiveDemo.colors" 
                    :key="color.value"
                    @click="directiveDemo.changeColor(color.value)"
                    class="color-button"
                    :style="{ backgroundColor: color.value }"
                    :class="{ active: directiveDemo.color === color.value }"
                  >
                    {{ color.name }}
                  </button>
                </div>
                <div 
                  v-highlight="directiveDemo.color"
                  class="highlight-box"
                >
                  高亮文本示例
                </div>
              </div>
              <div class="directive-section">
                <h4>点击外部</h4>
                <div 
                  v-click-outside="directiveDemo.handleClickOutside"
                  class="click-outside-box"
                  :class="{ active: directiveDemo.isActive }"
                >
                  <p>点击此区域激活</p>
                  <p v-if="directiveDemo.isActive">点击外部区域关闭</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Provide/Inject -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>Provide/Inject</h3>
          <button class="code-toggle" @click="toggleCode('provide')">
            {{ showCode.provide ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.provide">
            <pre class="code-viewer"><code>// Provide/Inject 示例
// 父组件
import { provide, ref } from 'vue'

const theme = ref('dark')
const updateTheme = (newTheme) => {
  theme.value = newTheme
}

provide('theme', {
  theme,
  updateTheme
})

// 子组件
import { inject } from 'vue'

const { theme, updateTheme } = inject('theme')

// 带默认值的注入
const message = inject('message', '默认消息')

// 只读注入
const readonlyTheme = inject('theme', null, true)</code></pre>
          </div>
          <div class="demo-preview">
            <div class="provide-demo">
              <div class="theme-selector">
                <h4>主题设置 (Provider)</h4>
                <div class="theme-options">
                  <button 
                    v-for="option in provideDemo.themeOptions" 
                    :key="option"
                    @click="provideDemo.updateTheme(option)"
                    :class="{ active: provideDemo.theme === option }"
                  >
                    {{ option }}
                  </button>
                </div>
              </div>
              <div class="theme-consumer">
                <h4>主题使用 (Consumer)</h4>
                <div 
                  class="theme-preview"
                  :class="provideDemo.theme"
                >
                  当前主题: {{ provideDemo.theme }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Fragment -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>Fragment</h3>
          <button class="code-toggle" @click="toggleCode('fragment')">
            {{ showCode.fragment ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.fragment">
            <pre class="code-viewer"><code>// Fragment 示例
// Vue 3 支持多根节点组件
&lt;template&gt;
  &lt;div class="header"&gt;头部&lt;/div&gt;
  &lt;div class="content"&gt;内容&lt;/div&gt;
  &lt;div class="footer"&gt;底部&lt;/div&gt;
&lt;/template&gt;

// 不需要包裹在一个根元素中
// 也可以使用显式的 Fragment
&lt;template&gt;
  &lt;Fragment&gt;
    &lt;div class="header"&gt;头部&lt;/div&gt;
    &lt;div class="content"&gt;内容&lt;/div&gt;
    &lt;div class="footer"&gt;底部&lt;/div&gt;
  &lt;/Fragment&gt;
&lt;/template&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="fragment-demo">
              <div class="fragment-container">
                <div class="fragment-header">头部</div>
                <div class="fragment-content">内容区域</div>
                <div class="fragment-footer">底部</div>
              </div>
              <div class="fragment-info">
                <p>Vue 3 支持多根节点组件，不需要包裹在一个根元素中</p>
                <p>这简化了组件结构，减少了不必要的DOM嵌套</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- SFC CSS 功能 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>SFC CSS 功能</h3>
          <button class="code-toggle" @click="toggleCode('css')">
            {{ showCode.css ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.css">
            <pre class="code-viewer"><code>// SFC CSS 功能示例
&lt;style scoped&gt;
/* 作用域样式 */
.component-class {
  color: blue;
}

/* 深度选择器 */
:deep(.child-class) {
  color: red;
}

/* 插槽选择器 */
:slotted(.slot-class) {
  color: green;
}

/* 全局选择器 */
:global(.global-class) {
  color: purple;
}

/* CSS 变量 */
:root {
  --primary-color: #42b883;
}

.component {
  color: var(--primary-color);
}
&lt;/style&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="css-demo">
              <div class="css-section">
                <h4>作用域样式</h4>
                <div class="scoped-box">
                  <p>这个样式只应用于当前组件</p>
                  <button class="scoped-button">作用域按钮</button>
                </div>
              </div>
              <div class="css-section">
                <h4>CSS 变量</h4>
                <div class="css-variables">
                  <div class="color-box primary">主色</div>
                  <div class="color-box secondary">次色</div>
                  <div class="color-box accent">强调色</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 响应式API进阶 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>响应式API进阶</h3>
          <button class="code-toggle" @click="toggleCode('reactivityAdvanced2')">
            {{ showCode.reactivityAdvanced2 ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.reactivityAdvanced2">
            <pre class="code-viewer"><code>// 响应式API进阶示例
import { 
  ref, 
  reactive, 
  computed, 
  watch, 
  watchEffect,
  nextTick,
  onMounted,
  onUnmounted,
  toRef,
  toRefs,
  isRef,
  isReactive,
  isReadonly,
  isProxy,
  unref
} from 'vue'

// 使用 toRef 创建属性的引用
const state = reactive({ count: 0 })
const countRef = toRef(state, 'count')

// 使用 toRefs 解构响应式对象
const { count, name } = toRefs(state)

// 使用 nextTick 等待DOM更新
const updateAndLog = async () => {
  state.count++
  await nextTick()
  console.log('DOM已更新')
}

// 类型检查
const isRefValue = isRef(countRef)
const isReactiveValue = isReactive(state)
const isReadonlyValue = isReadonly(readonly(state))
const isProxyValue = isProxy(state)

// 解包ref
const unwrapped = unref(countRef)</code></pre>
          </div>
          <div class="demo-preview">
            <div class="reactivity-advanced2-demo">
              <div class="reactivity-section">
                <h4>toRef/toRefs 示例</h4>
                <div class="reactivity-controls">
                  <button @click="reactivityAdvanced2Demo.incrementCount">增加计数</button>
                  <button @click="reactivityAdvanced2Demo.updateName">更新名称</button>
                </div>
                <div class="reactivity-display">
                  <div class="reactivity-item">
                    <span class="reactivity-label">计数:</span>
                    <span class="reactivity-value">{{ reactivityAdvanced2Demo.count }}</span>
                  </div>
                  <div class="reactivity-item">
                    <span class="reactivity-label">名称:</span>
                    <span class="reactivity-value">{{ reactivityAdvanced2Demo.name }}</span>
                  </div>
                </div>
              </div>
              <div class="reactivity-section">
                <h4>nextTick 示例</h4>
                <div class="next-tick-demo">
                  <div class="next-tick-display">
                    <div class="next-tick-item">
                      <span class="next-tick-label">消息:</span>
                      <span class="next-tick-value">{{ reactivityAdvanced2Demo.message }}</span>
                    </div>
                    <div class="next-tick-item">
                      <span class="next-tick-label">更新状态:</span>
                      <span class="next-tick-value">{{ reactivityAdvanced2Demo.updateStatus }}</span>
                    </div>
                  </div>
                  <button @click="reactivityAdvanced2Demo.updateWithNextTick">使用nextTick更新</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- TypeScript 支持 -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>TypeScript 支持</h3>
          <button class="code-toggle" @click="toggleCode('typescript')">
            {{ showCode.typescript ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.typescript">
            <pre class="code-viewer"><code>// TypeScript 支持示例
&lt;script setup lang="ts"&gt;
import { ref, computed } from 'vue'

// 类型定义
interface User {
  id: number
  name: string
  email: string
  role: 'admin' | 'user' | 'guest'
}

// 泛型响应式引用
const user = ref&lt;User&gt;({
  id: 1,
  name: 'Vue',
  email: 'vue@example.com',
  role: 'admin'
})

// 类型化计算属性
const userDisplayName = computed&lt;string&gt;(() => {
  return `${user.value.name} (${user.value.role})`
})

// 类型化函数
function updateUserRole(newRole: User['role']): void {
  user.value.role = newRole
}

// 类型化事件
const emit = defineEmits&lt;{
  (e: 'update', user: User): void
  (e: 'delete', id: number): void
}&gt;()

// 类型化Props
const props = defineProps&lt;{
  title: string
  count?: number
  user?: User
}&gt;()</code></pre>
          </div>
          <div class="demo-preview">
            <div class="typescript-demo">
              <div class="typescript-section">
                <h4>类型化数据</h4>
                <div class="user-card">
                  <div class="user-header">
                    <span class="user-id">#{{ typescriptDemo.user.id }}</span>
                    <span class="user-role" :class="typescriptDemo.user.role">
                      {{ typescriptDemo.user.role }}
                    </span>
                  </div>
                  <div class="user-info">
                    <div class="user-name">{{ typescriptDemo.user.name }}</div>
                    <div class="user-email">{{ typescriptDemo.user.email }}</div>
                  </div>
                </div>
              </div>
              <div class="typescript-section">
                <h4>类型化操作</h4>
                <div class="role-selector">
                  <button 
                    v-for="role in typescriptDemo.roles" 
                    :key="role"
                    @click="typescriptDemo.updateRole(role)"
                    :class="{ active: typescriptDemo.user.role === role }"
                  >
                    {{ role }}
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 组件API -->
      <div class="demo-card">
        <div class="demo-header">
          <h3>组件API</h3>
          <button class="code-toggle" @click="toggleCode('componentApi')">
            {{ showCode.componentApi ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.componentApi">
            <pre class="code-viewer"><code>// 组件API示例
import { defineComponent, h, resolveComponent } from 'vue'

// 使用defineComponent定义组件
export default defineComponent({
  name: 'MyComponent',
  props: {
    title: String,
    count: Number
  },
  setup(props) {
    const count = ref(0)
    
    // 使用h函数创建虚拟DOM
    const renderTitle = () => h('h2', { class: 'title' }, props.title)
    
    // 动态解析组件
    const MyButton = resolveComponent('MyButton')
    
    return () => h('div', { class: 'my-component' }, [
      renderTitle(),
      h(MyButton, { onClick: () => count.value++ }, () => `点击次数: ${count.value}`)
    ])
  }
})

// 使用JSX
const MyComponent = defineComponent({
  setup() {
    return () => (
      &lt;div class="my-component"&gt;
        &lt;h2&gt;标题&lt;/h2&gt;
        &lt;button onClick={() => count.value++}&gt;
          点击次数: {count.value}
        &lt;/button&gt;
      &lt;/div&gt;
    )
  }
})</code></pre>
          </div>
          <div class="demo-preview">
            <div class="component-api-demo">
              <div class="component-section">
                <h4>动态组件</h4>
                <div class="dynamic-component">
                  <div class="component-controls">
                    <button 
                      v-for="name in componentApiDemo.components" 
                      :key="name"
                      @click="componentApiDemo.currentComponent = name"
                      :class="{ active: componentApiDemo.currentComponent === name }"
                    >
                      {{ name }}
                    </button>
                  </div>
                  <div class="component-display">
                    <component :is="componentApiDemo.currentComponent" />
                  </div>
                </div>
              </div>
              <div class="component-section">
                <h4>组件渲染</h4>
                <div class="render-demo">
                  <div class="render-controls">
                    <button @click="componentApiDemo.toggleRender">切换渲染</button>
                  </div>
                  <div class="render-display">
                    <div v-if="componentApiDemo.showRenderA" class="render-a">
                      渲染A
                    </div>
                    <div v-else class="render-b">
                      渲染B
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, watchEffect, onMounted, onUnmounted, readonly, shallowReactive, toRaw, markRaw, customRef, nextTick, toRef, toRefs, isRef, isReactive, isReadonly, isProxy, unref, h, resolveComponent, defineComponent } from 'vue'

// 代码显示状态
const showCode = ref({
  composition: false,
  setup: false,
  teleport: false,
  suspense: false,
  reactivity: false,
  compositionAdvanced: false,
  reactivityAdvanced: false,
  directive: false,
  provide: false,
  fragment: false,
  css: false,
  reactivityAdvanced2: false,
  typescript: false,
  componentApi: false
})

const toggleCode = (section) => {
  showCode.value[section] = !showCode.value[section]
}

// Composition API 演示
const compositionDemo = reactive({
  count: 0,
  doubleCount: computed(() => compositionDemo.count * 2),
  lastAction: '',
  increment() {
    this.count++
    this.lastAction = '增加'
  },
  decrement() {
    this.count--
    this.lastAction = '减少'
  },
  reset() {
    this.count = 0
    this.lastAction = '重置'
  }
})

// Script Setup 演示
const setupDemo = reactive({
  count: 0,
  increment() {
    this.count++
  },
  decrement() {
    this.count--
  }
})

// Teleport 演示
const teleportDemo = reactive({
  showModal: false
})

// Suspense 演示
const suspenseDemo = reactive({
  data: null,
  loading: false,
  error: null
})

const loadSuspenseData = async () => {
  suspenseDemo.loading = true
  suspenseDemo.error = null
  try {
    await new Promise(resolve => setTimeout(resolve, 1000))
    suspenseDemo.data = {
      id: Math.floor(Math.random() * 1000),
      title: '异步数据示例',
      timestamp: new Date().toLocaleString(),
      status: ['成功', '处理中', '等待中'][Math.floor(Math.random() * 3)],
      type: ['用户数据', '订单数据', '商品数据'][Math.floor(Math.random() * 3)]
    }
  } catch (err) {
    suspenseDemo.error = '数据加载失败：' + err.message
  } finally {
    suspenseDemo.loading = false
  }
}

// 响应式系统演示
const reactivityDemo = reactive({
  message: 'Hello Vue 3',
  user: {
    name: 'Vue',
    age: 3
  },
  get userInfo() {
    return `${this.user.name} (${this.user.age}岁)`
  }
})

// 组合式API进阶演示
const mousePosition = reactive({
  x: 0,
  y: 0
})

const updateMousePosition = (e) => {
  mousePosition.x = e.clientX
  mousePosition.y = e.clientY
}

const debounceInput = ref('')
const debounceResult = ref('')

// 防抖处理
watch(debounceInput, (newValue) => {
  const timeout = setTimeout(() => {
    debounceResult.value = newValue
  }, 500)
  return () => clearTimeout(timeout)
})

// 响应式系统进阶演示
const reactivityAdvancedDemo = reactive({
  original: reactive({ count: 0 }),
  copy: readonly(reactive({ count: 0 })),
  shallowState: shallowReactive({
    value: 0,
    nested: { count: 0 }
  }),
  incrementOriginal() {
    this.original.count++
  },
  tryModifyCopy() {
    try {
      this.copy.count++
    } catch (err) {
      console.warn('无法修改只读数据:', err)
    }
  },
  updateNested() {
    this.shallowState.value++
    this.shallowState.nested.count++
  }
})

// 自定义指令演示
const directiveDemo = reactive({
  color: '#ff0',
  colors: [
    { name: '黄色', value: '#ff0' },
    { name: '绿色', value: '#0f0' },
    { name: '蓝色', value: '#0ff' },
    { name: '红色', value: '#f00' }
  ],
  isActive: false,
  changeColor(color) {
    this.color = color
  },
  handleClickOutside() {
    this.isActive = !this.isActive
  }
})

// 自定义指令定义
const vFocus = {
  mounted: (el) => el.focus()
}

const vHighlight = {
  mounted: (el, binding) => {
    el.style.backgroundColor = binding.value || '#ff0'
  },
  updated: (el, binding) => {
    el.style.backgroundColor = binding.value || '#ff0'
  }
}

const vClickOutside = {
  mounted(el, binding) {
    el._clickOutside = (event) => {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event)
      }
    }
    document.addEventListener('click', el._clickOutside)
  },
  unmounted(el) {
    document.removeEventListener('click', el._clickOutside)
  }
}

// Provide/Inject 演示
const provideDemo = reactive({
  theme: 'dark',
  themeOptions: ['light', 'dark', 'system'],
  updateTheme(newTheme) {
    this.theme = newTheme
  }
})

// Fragment 演示
const fragmentDemo = reactive({
  message: 'Vue 3 支持多根节点组件'
})

// SFC CSS 功能演示
const cssDemo = reactive({
  primaryColor: '#42b883',
  secondaryColor: '#35495e',
  accentColor: '#ff7e67'
})

// 响应式API进阶2演示
const reactivityAdvanced2Demo = reactive({
  count: 0,
  name: 'Vue 3',
  message: '初始消息',
  updateStatus: '未更新',
  incrementCount() {
    this.count++
  },
  updateName() {
    this.name = this.name === 'Vue 3' ? 'Vue.js' : 'Vue 3'
  },
  async updateWithNextTick() {
    this.message = '更新中...'
    this.updateStatus = '正在更新'
    
    await nextTick()
    
    this.message = '已更新!'
    this.updateStatus = '更新完成'
    
    setTimeout(() => {
      this.message = '初始消息'
      this.updateStatus = '未更新'
    }, 2000)
  }
})

// TypeScript 支持演示
const typescriptDemo = reactive({
  user: {
    id: 1,
    name: 'Vue',
    email: 'vue@example.com',
    role: 'admin'
  },
  roles: ['admin', 'user', 'guest'],
  updateRole(role) {
    this.user.role = role
  }
})

// 组件API演示
const componentApiDemo = reactive({
  currentComponent: 'ComponentA',
  components: ['ComponentA', 'ComponentB', 'ComponentC'],
  showRenderA: true,
  toggleRender() {
    this.showRenderA = !this.showRenderA
  }
})

// 定义动态组件
const ComponentA = defineComponent({
  render() {
    return h('div', { class: 'dynamic-component-a' }, '组件 A')
  }
})

const ComponentB = defineComponent({
  render() {
    return h('div', { class: 'dynamic-component-b' }, '组件 B')
  }
})

const ComponentC = defineComponent({
  render() {
    return h('div', { class: 'dynamic-component-c' }, '组件 C')
  }
})
</script>

<style scoped>
.vue3-demo {
  padding: 2rem;
}

.section-title {
  font-size: 2.5rem;
  margin-bottom: 2rem;
  text-align: center;
  background: linear-gradient(45deg, var(--primary-color), var(--secondary-color));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

.demo-card {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 15px;
  padding: 1.5rem;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.demo-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.demo-header h3 {
  font-size: 1.5rem;
  margin: 0;
  color: var(--primary-color);
}

.code-toggle {
  background: rgba(0, 255, 136, 0.1);
  border: 1px solid rgba(0, 255, 136, 0.3);
  color: #00ff88;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.code-toggle:hover {
  background: rgba(0, 255, 136, 0.2);
}

.demo-content {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.code-block {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
  overflow: hidden;
}

.code-viewer {
  width: 100%;
  margin: 0;
  padding: 1rem;
  background: transparent;
  color: #b8e0d2;
  font-family: 'Fira Code', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-x: auto;
}

.feature-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.feature-item {
  display: flex;
  justify-content: space-between;
  padding: 0.5rem;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
  transition: background-color 0.3s ease;
}

.feature-item:hover {
  background: rgba(0, 0, 0, 0.3);
}

.feature-label {
  color: var(--primary-color);
}

.feature-value {
  font-family: monospace;
}

.interactive-demo {
  margin-top: 1rem;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
}

.input-group {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.input-group input {
  flex: 1;
  min-width: 150px;
  padding: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.2);
  color: var(--text-color);
}

.result-display {
  padding: 0.5rem;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 5px;
  white-space: pre-wrap;
  font-family: 'Fira Code', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
}

button {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 5px;
  background: linear-gradient(45deg, var(--primary-color), var(--secondary-color));
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
}

button:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(0, 255, 136, 0.2);
}

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal {
  background: rgba(0, 0, 0, 0.9);
  padding: 2rem;
  border-radius: 15px;
  border: 1px solid rgba(0, 255, 136, 0.3);
  backdrop-filter: blur(10px);
  max-width: 90%;
  width: 400px;
}

.modal h3 {
  margin-top: 0;
  color: var(--primary-color);
}

.counter-card {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 15px;
  padding: 2rem;
  text-align: center;
}

.counter-display {
  font-size: 4rem;
  font-weight: bold;
  margin-bottom: 1.5rem;
  font-family: monospace;
  color: var(--primary-color);
}

.counter-controls {
  display: flex;
  justify-content: center;
  gap: 1rem;
}

.primary-button {
  padding: 0.75rem 1rem;
  border: none;
  border-radius: 20px;
  background: linear-gradient(45deg, var(--primary-color), var(--secondary-color));
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.3s ease;
}

.primary-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(0, 255, 136, 0.2);
}

.error-message {
  padding: 1rem;
  text-align: center;
  color: #ff4444;
  background: rgba(255, 0, 0, 0.1);
  border-radius: 5px;
}

.data-card {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 10px;
  padding: 1.5rem;
  margin-top: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.data-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.data-id {
  color: var(--primary-color);
  font-family: monospace;
}

.data-timestamp {
  color: rgba(255, 255, 255, 0.5);
  font-size: 0.9rem;
}

.data-content h4 {
  margin: 0 0 1rem 0;
  color: var(--text-color);
}

.data-info {
  display: flex;
  gap: 1rem;
}

.data-status {
  padding: 0.25rem 0.75rem;
  border-radius: 15px;
  font-size: 0.9rem;
}

.data-status.成功 {
  background: rgba(76, 175, 80, 0.2);
  color: #4caf50;
}

.data-status.处理中 {
  background: rgba(255, 193, 7, 0.2);
  color: #ffc107;
}

.data-status.等待中 {
  background: rgba(33, 150, 243, 0.2);
  color: #2196f3;
}

.data-type {
  color: rgba(255, 255, 255, 0.7);
}

/* 组合式API进阶样式 */
.advanced-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.mouse-tracker {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.mouse-tracker h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.position-display {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
}

.position-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.position-label {
  color: var(--primary-color);
}

.position-value {
  font-family: monospace;
  font-size: 1.2rem;
}

.mouse-area {
  height: 150px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  border: 1px dashed rgba(255, 255, 255, 0.2);
  cursor: crosshair;
}

.debounce-demo {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.debounce-demo h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.debounce-input {
  width: 100%;
  padding: 0.75rem;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--text-color);
  margin-bottom: 1rem;
}

.debounce-result {
  padding: 0.75rem;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 5px;
  font-family: monospace;
}

/* 响应式系统进阶样式 */
.advanced-reactivity-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.reactivity-section {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.reactivity-section h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.reactivity-controls {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.reactivity-display {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.reactivity-item {
  display: flex;
  justify-content: space-between;
  padding: 0.5rem;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 5px;
}

.reactivity-label {
  color: var(--primary-color);
}

.reactivity-value {
  font-family: monospace;
}

/* 自定义指令样式 */
.directive-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.directive-section {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.directive-section h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.directive-input {
  width: 100%;
  padding: 0.75rem;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--text-color);
}

.color-picker {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.color-button {
  padding: 0.5rem 1rem;
  border-radius: 20px;
  color: rgba(0, 0, 0, 0.8);
  font-weight: bold;
}

.color-button.active {
  transform: scale(1.05);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

.highlight-box {
  padding: 2rem;
  text-align: center;
  font-size: 1.2rem;
  border-radius: 10px;
  transition: all 0.3s ease;
}

.click-outside-box {
  padding: 2rem;
  text-align: center;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.click-outside-box.active {
  background: rgba(0, 255, 136, 0.1);
  border-color: rgba(0, 255, 136, 0.3);
}

/* Provide/Inject 样式 */
.provide-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.theme-selector,
.theme-consumer {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.theme-selector h4,
.theme-consumer h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.theme-options {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}

.theme-preview {
  padding: 2rem;
  border-radius: 10px;
  text-align: center;
  transition: all 0.3s ease;
}

.theme-preview.light {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.theme-preview.dark {
  background: rgba(0, 0, 0, 0.4);
  color: #fff;
}

.theme-preview.system {
  background: linear-gradient(45deg, rgba(255, 255, 255, 0.1), rgba(0, 0, 0, 0.4));
  color: #fff;
}

@media (max-width: 768px) {
  .input-group {
    flex-direction: column;
  }
  
  .theme-options {
    flex-direction: column;
  }
  
  .color-picker {
    flex-wrap: wrap;
  }
}

/* Fragment 样式 */
.fragment-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.fragment-container {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.fragment-header {
  background: rgba(0, 0, 0, 0.2);
  padding: 1rem;
  border-radius: 10px 10px 0 0;
  text-align: center;
  color: var(--primary-color);
  font-weight: bold;
}

.fragment-content {
  background: rgba(0, 0, 0, 0.3);
  padding: 2rem;
  text-align: center;
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fragment-footer {
  background: rgba(0, 0, 0, 0.2);
  padding: 1rem;
  border-radius: 0 0 10px 10px;
  text-align: center;
  color: var(--secondary-color);
}

.fragment-info {
  background: rgba(0, 0, 0, 0.2);
  padding: 1rem;
  border-radius: 10px;
  font-size: 0.9rem;
  line-height: 1.5;
}

/* SFC CSS 功能样式 */
.css-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.css-section {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.css-section h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.scoped-box {
  padding: 1.5rem;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  text-align: center;
}

.scoped-button {
  margin-top: 1rem;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  background: var(--primary-color);
  color: white;
  border: none;
  cursor: pointer;
}

.css-variables {
  display: flex;
  gap: 1rem;
  margin-top: 1rem;
}

.color-box {
  flex: 1;
  padding: 2rem;
  border-radius: 10px;
  text-align: center;
  font-weight: bold;
  color: white;
}

.color-box.primary {
  background: var(--primary-color);
}

.color-box.secondary {
  background: var(--secondary-color);
}

.color-box.accent {
  background: var(--accent-color);
}

/* 响应式API进阶2样式 */
.reactivity-advanced2-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.next-tick-demo {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.next-tick-display {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.next-tick-item {
  display: flex;
  justify-content: space-between;
  padding: 0.5rem;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 5px;
}

.next-tick-label {
  color: var(--primary-color);
}

.next-tick-value {
  font-family: monospace;
}

/* TypeScript 支持样式 */
.typescript-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.typescript-section {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.typescript-section h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.user-card {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  overflow: hidden;
}

.user-header {
  display: flex;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  background: rgba(0, 0, 0, 0.4);
}

.user-id {
  color: var(--primary-color);
  font-family: monospace;
}

.user-role {
  padding: 0.25rem 0.75rem;
  border-radius: 15px;
  font-size: 0.8rem;
  font-weight: bold;
}

.user-role.admin {
  background: rgba(255, 0, 0, 0.2);
  color: #ff4444;
}

.user-role.user {
  background: rgba(0, 255, 0, 0.2);
  color: #44ff44;
}

.user-role.guest {
  background: rgba(0, 0, 255, 0.2);
  color: #4444ff;
}

.user-info {
  padding: 1rem;
}

.user-name {
  font-size: 1.2rem;
  font-weight: bold;
  margin-bottom: 0.5rem;
}

.user-email {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.9rem;
}

.role-selector {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}

.role-selector button {
  flex: 1;
  padding: 0.5rem;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.3s ease;
}

.role-selector button.active {
  background: var(--primary-color);
  color: white;
}

/* 组件API样式 */
.component-api-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.component-section {
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  border-radius: 10px;
}

.component-section h4 {
  margin-top: 0;
  color: var(--primary-color);
}

.dynamic-component {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.component-controls {
  display: flex;
  gap: 0.5rem;
}

.component-controls button {
  flex: 1;
  padding: 0.5rem;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.3s ease;
}

.component-controls button.active {
  background: var(--primary-color);
  color: white;
}

.component-display {
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  padding: 1rem;
}

.dynamic-component-a {
  color: #ff4444;
  font-weight: bold;
}

.dynamic-component-b {
  color: #44ff44;
  font-weight: bold;
}

.dynamic-component-c {
  color: #4444ff;
  font-weight: bold;
}

.render-demo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.render-controls {
  display: flex;
  justify-content: center;
}

.render-display {
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  padding: 1rem;
}

.render-a {
  color: #ff4444;
  font-weight: bold;
}

.render-b {
  color: #44ff44;
  font-weight: bold;
}

@media (max-width: 768px) {
  .input-group {
    flex-direction: column;
  }
  
  .theme-options {
    flex-direction: column;
  }
  
  .color-picker {
    flex-wrap: wrap;
  }
  
  .css-variables {
    flex-direction: column;
  }
  
  .role-selector {
    flex-direction: column;
  }
  
  .component-controls {
    flex-direction: column;
  }
}
</style> 